package com.dog.basics.security.controller;


import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Map;
import javax.imageio.ImageIO;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.dog.basics.common.util.OSUtil;
import com.dog.basics.common.util.R;
import com.dog.basics.common.util.RedisUtil;
import com.dog.basics.security.constants.SecurityConstants;
import com.dog.basics.security.util.VerifyImageUtil;
import com.dog.basics.security.util.WordCodeEnum;
import com.dog.basics.security.util.WordCodeTemplatesEnum;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.cache.CacheManager;
import org.springframework.http.HttpHeaders;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2RefreshToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.*;

import springfox.documentation.annotations.ApiIgnore;

/**
 * 登录相关
 * @author dog
 */
@RestController
@AllArgsConstructor
@ApiIgnore
@Log4j2
public class SysLoginController {

	private final CacheManager cacheManager;
	private final TokenStore tokenStore;


	/**
	 * 退出
	 */
	@PostMapping(value = "/sys/logout")
	public R logout(@RequestHeader(value = HttpHeaders.AUTHORIZATION, required = false) String authHeader) {
		if (StrUtil.isBlank(authHeader)) {
			return R.ok(Boolean.FALSE, "退出失败，token 为空");
		}

		String tokenValue = authHeader.replace(OAuth2AccessToken.BEARER_TYPE.toLowerCase(), StrUtil.EMPTY).trim();
		System.out.println(tokenValue);
		OAuth2AccessToken accessToken = tokenStore.readAccessToken(tokenValue);
		if (accessToken == null || StrUtil.isBlank(accessToken.getValue())) {
			return R.ok(Boolean.TRUE, "退出失败，token 无效");
		}
		// 获取用户信息
		OAuth2Authentication auth2Authentication = tokenStore.readAuthentication(accessToken);

		// 清空access token
		tokenStore.removeAccessToken(accessToken);

		// 清空 refresh token
		OAuth2RefreshToken refreshToken = accessToken.getRefreshToken();
		tokenStore.removeRefreshToken(refreshToken);
		return R.ok();
	}

	/**
	 * @Author: guoy
	 * @Param: [serverRequest]
	 * @Return: reactor.core.publisher.Mono<org.springframework.web.reactive.function.server.ServerResponse>
	 * @Date: 2019/12/13 11:32
	 * 功能描述：滑动验证码
	 * @return
	 */
	@GetMapping("/code")
	public R<Map<String, Object>> code(String randomStr) {

		// 原图获取流
		String primaryFormatUrl = StrUtil.format("wordCodeImg/{}", WordCodeEnum.getMessageByCode(RandomUtil.randomInt(WordCodeEnum.values().length)));
		InputStream primaryStream = ResourceUtil.getStream(primaryFormatUrl);

		// 模板图
		InputStream templaStream = ResourceUtil.getStream("wordCodeImg/templates/" + WordCodeTemplatesEnum.getMessageByCode(RandomUtil.randomInt(WordCodeTemplatesEnum.values().length)));

		//生成验证码  -- 开始
		Map<String, Object> resultMap = null;
		try {
			// 根据模板裁剪图片
			resultMap = VerifyImageUtil.pictureTemplatesCut(templaStream, primaryStream);
			//保存验证码信息
			Integer xWidth = (Integer) resultMap.get("xWidth");
			RedisUtil.set(SecurityConstants.SPRING_SECURITY_RESTFUL_IMAGE_CODE + randomStr, xWidth, SecurityConstants.CODE_TIME);
			// 移除横坐标送前端
			resultMap.remove("xWidth");
			// 新建流。
			resultMap.put("image", Base64Utils.encodeToString(IoUtil.readBytes(ResourceUtil.getStream(primaryFormatUrl))));
		} catch (Exception e) {
			log.error("ImageIO write err", e);
		}
		return R.ok(resultMap);
	}
}
